package com.yc.net;

import javax.swing.*;
import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Arrays;
import java.util.Scanner;

public class QQServer {

    public static void main(String[] args) throws IOException, InterruptedException {
        ServerSocket server = new ServerSocket(9999);
        System.out.println("服务器启动监听段端口:9999");
        // IO操作, 阻塞
        Socket socket = server.accept();

        InetAddress inetAddress = socket.getInetAddress();
        System.out.println("主机地址 = " + inetAddress.getHostAddress());
        byte[] address = inetAddress.getAddress();
        System.out.println("IP地址 = " + Arrays.toString(address));
        System.out.println("主机名 = " + inetAddress.getHostName());
        // 获取输入输出流
        InputStream in = socket.getInputStream();
        OutputStream out = socket.getOutputStream();
        // 屏幕输入对象
        Scanner scanner = new Scanner(System.in);

        Thread readThread = new Thread(() -> {
            boolean running = true;
            while (running) {
                try {
                    recv(in);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        });

        Thread writeThread = new Thread(() -> {
            boolean running = true;
            while (running) {
                Object data = input(scanner);
                try {
                    send(data, out);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        });

        readThread.start();
        writeThread.start();

        // 等待读写线程结束, 主线程才执行关闭的代码
        readThread.join();
        writeThread.join();

        // Unreachable statement 代码不可达
        in.close();
        out.close();
        socket.close();

    }

    // 用户输入文字或文件
    public static Object input(Scanner scanner) {
        System.out.print("请选择发送文字(1)或是文件(2):");
        String s = scanner.nextLine();
        if ("2".equals(s)) {
            JFileChooser jFileChooser = new JFileChooser();
            int i = jFileChooser.showOpenDialog(null);
            if (i == JFileChooser.APPROVE_OPTION) {
                // 用户选择了一个文件, 返回选择的文件
                return jFileChooser.getSelectedFile();
            }
        } else {
            // 默认文字
            System.out.print("请输入文字:");
            return scanner.nextLine();
        }
        return null;
    }

    public static void sendText(String msg, OutputStream out) throws IOException {
        DataOutputStream dos = new DataOutputStream(out);
        dos.writeInt(1);
        // 发送文字
        out.write(msg.getBytes());
    }

    public static void sendFile(File file, OutputStream out) throws IOException {
        DataOutputStream dos = new DataOutputStream(out);
        dos.writeInt(2);
        // 发送文件名
        dos.writeUTF(file.getName());
        // 发送文件大小
        dos.writeLong(file.length());
        // 发送文件内容
        try (FileInputStream fis = new FileInputStream(file)) {
            byte[] bytes = new byte[1024];
            int count;
            while ((count = fis.read(bytes)) > 0) {
                out.write(bytes, 0, count);
            }
        }
    }

    public static void recv(InputStream in) throws IOException {
        DataInputStream dis = new DataInputStream(in);
        int i = dis.readInt();
        if (i == 1) {
            byte[] bytes = new byte[1024];
            int count;
            count = in.read(bytes);
            String msg = new String(bytes,0,count);
            System.out.println("对方说:" + msg);
        } else if (i == 2) {
            String filename = dis.readUTF();
            long length = dis.readLong(); // 文件大小
            System.out.println("接收到文件: " + filename);
            String filepath = "D:\\_文件柜\\133\\0922\\" + filename;
            try (FileOutputStream fos = new FileOutputStream(filepath)) {
                byte[] bytes = new byte[1024];
                int count;
                long readLength = 0;
                while ((count = in.read(bytes)) > 0) {
                    readLength += count;  //  记录读取的字节数
                    fos.write(bytes, 0, count);
                    // 读完就退出
                    if(readLength >= length){
                        break;
                    }
                }
            }
            System.out.println("文件保存到: " + filepath);
        }
    }

    public static void send(Object object, OutputStream out) throws IOException {
        if (object instanceof String) {
            String msg = (String) object;
            sendText(msg, out);
        } else if (object instanceof File) {
            File file = (File) object;
            sendFile(file, out);
        } else {
            System.out.println("未知格式数据: " + object);
        }
    }
}
